import urequests

from beeos import TimerOSKernel, WifiConnectProcess, KernelApi, Ap
from config import Config
from config import ConfigController
from device_ctl import device_ctl_process, KeyControllerProcess
from http_server import HttpServer
from log import Log
from message import MessageProcess
from rtc import RTCHelper

log = Log(tag='main')
conf = Config()
ap = Ap('LEVENT', '88888888')


class DeviceStatusSyncHelper:
    def __init__(self, ctl):
        self.ctl = ctl
        self.url = conf.get(['server', 'syncUrl'], None)
        if self.url:
            self.url += ('?sn=%s' % KernelApi.get_sn())

    def do_sync(self):
        if not self.url:
            log.warn('Skip state sync,empty url!')
            return
        resp = urequests.get(self.url)
        resp = resp.json()
        if ('code' not in resp) or (resp['code'] != 200):
            log.error('E:SYNC STATE')
            return
        data = resp['data']
        status = data['status']
        now = data['timestamp']
        motor1 = status['motor1']
        motor2 = status['motor2']
        state = {
            'motor1': motor1,
            'motor2': motor2,
        }
        self.ctl.set_state(state)
        time = RTCHelper.parse(now)
        RTCHelper.set_time(*time)
        device_ctl_process.set_rtc_ready(True)
        log.info('Sync state:[%s]' % now)


class Main:
    def __init__(self, kernel, config):
        self.kernel = kernel
        self.conf = config
        self.ap_started = False
        self.message_task = None

    def _on_wifi_ready(self):
        log.debug('WIFI connected!Sync state')
        Main._sync_state()
        log.info('State sync complete!')
        conf_names = ['server', 'msgHost']
        host = self.conf.get(conf_names)
        conf_names[1] = 'msgPort'
        port = self.conf.get(conf_names)
        conf_names[1] = 'msgUser'
        user = self.conf.get(conf_names)
        conf_names[1] = 'msgPassword'
        password = self.conf.get(conf_names)
        conf_names[1] = 'topicDown'
        topic_down = self.conf.get(conf_names)
        conf_names[1] = 'topicUp'
        topic_up = self.conf.get(conf_names)
        self.message_task = MessageProcess(host, port, user, password, topic_down, topic_up)
        self.kernel.exec(self.message_task)

    @staticmethod
    def _sync_state():
        try:
            helper = DeviceStatusSyncHelper(device_ctl_process)
            helper.do_sync()
        except Exception as e:
            log.error('Sync state Error', e)

    def _start_ap(self):
        if self.ap_started:
            return
        self.ap_started = True
        log.info('Starting AP...')
        ap.start()
        log.info('Starting Http Server...')
        self.init_server()
        log.info('Config ready!')

    def start(self):
        ssid = self.conf.get(['wifi', 'ssid'])
        passwd = self.conf.get(['wifi', 'password'])
        wifi_task = WifiConnectProcess(ssid, passwd, lambda: self._on_wifi_ready())
        log.info('Starting wifi task...')
        self.kernel.exec(wifi_task)
        log.info('Starting device task...')
        self.kernel.exec(device_ctl_process)
        key_ctl_proc = KeyControllerProcess(on_change=lambda: self._on_device_state_change(),
                                            on_long_press=lambda: self._start_ap())
        log.info("Starting key ctl proc...")
        self.kernel.exec(key_ctl_proc)
        log.info("Started!")

    def _on_device_state_change(self):
        if not self.message_task:
            return
        self.message_task.report_state()

    def init_server(self):
        server = HttpServer()
        server.mapping.add_mapping('/conf', ConfigController())
        log.info('Starting http task...')
        self.kernel.exec(server)


def main():
    log.info('SN:[%s]' % KernelApi.get_sn())
    conf.load()
    kernel = TimerOSKernel()
    kernel.setup_os()
    log.info('Starting kernel...')
    kernel.run_forever()
    log.info('Starting main...')
    Main(kernel, conf).start()


if __name__ == '__main__':
    main()
